package com.xiaotu.spider.project.pageprocessor.list;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import com.google.gson.Gson;
import com.xiaotu.common.exception.SpiderException;
import com.xiaotu.common.exception.SpiderExceptionCode;
import com.xiaotu.common.util.Constants;
import com.xiaotu.common.util.FileUtil;
import com.xiaotu.common.util.HttpUtils;
import com.xiaotu.common.util.KeywordEncode;
import com.xiaotu.common.util.PageUtils;
import com.xiaotu.common.util.SepratorUtil;
import com.xiaotu.common.util.StringUtil;
import com.xiaotu.spider.AUrlPageProcessor;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import us.codecraft.webmagic.Page;
import us.codecraft.webmagic.selector.Html;

/**
 * @类名 LeTVCommentListPageProcessor
 * @日期 2017年8月29日
 * @作者 王艳龙
 * @功能  乐视爬取类--TV 短评
 */
@Component("LeTVCommentListPageProcessor")
@Scope("prototype")
public class LeTVCommentListPageProcessor extends AUrlPageProcessor
{
	
    private String fileName; //读取tvName文件路径
    private String LeTVComment; //乐视短评
    
    @Override
    protected String[] getStartRequestUrls()
    {
        List<JSONObject> targetList = readFileColumn(fileName); //读取excel电影名
        List<String> linkList = new ArrayList<String>();
        for (JSONObject target : targetList)
        {
            linkList.add("http://so.le.com/s?wd="
				+ KeywordEncode.encode(target.getString("tvName")));
        }
        String[] urlArr = new String[linkList.size()];
        linkList.toArray(urlArr);
        return urlArr;

    }

    @Override
    public void initRunParams(Map<String, Object> map)
    {
        if (map.get("fileName") == null)
            throw new SpiderException(
                    SpiderExceptionCode.PageProcessorParameterErrorException);
        fileName = map.get("fileName") + StringUtils.EMPTY;

        if (map.get("LeTVComment") == null)
            throw new SpiderException(
                    SpiderExceptionCode.PageProcessorParameterErrorException);
        LeTVComment = map.get("LeTVComment") + StringUtils.EMPTY;
    }

    @Override
    public String getPageDataType(Page page)
    {
    	String url = page.getUrl().toString();
		if (url.contains("http://so.le.com/s?wd="))
			return Constants.PageDataType.SEARCH_LIST;
		else if (url.contains("http://www.letv.com/ptv/vplay"))
			return Constants.PageDataType.TV_RECORD;
		else if (url.contains("http://api.my.le.com/vcm/api/list"))
			return Constants.PageDataType.TV_COMMENT;
		else
			return Constants.PageDataType.SEARCH_LIST;
    }

    @Override
    public void process(Page page)
    {
    	Map<String, Object> tvMap = page.getRequest().getExtras();
		switch (this.getPageDataType(page))
		{
			case Constants.PageDataType.SEARCH_LIST:
				this.searchListProcess(page, tvMap);
				break;
			case Constants.PageDataType.TV_RECORD:
				this.tvRecordProcess(page, tvMap);
				break;
			case Constants.PageDataType.TV_COMMENT:
				this.commentProcess(page, tvMap);
				break;
			default:
				break;
		}
    }

    private void searchListProcess(Page page, final Map<String, Object> tvMap)
	{
		Html html = page.getHtml();
		//网大名称
		String movieName =html.xpath("//div[@class='info-tit']/h1/a[@class='j-baidu-a']/@title").toString();
		if(StringUtils.isNotEmpty(movieName)){
			tvMap.put("movieName", movieName);
		}
		// 链接标签
		String linkUrl = html.xpath("//div[@class='play-box j-play-list']/a[@class='ico_play']/@href").toString();
		if(StringUtils.isNotEmpty(linkUrl)){
			PageUtils.addTargetRequest(page,linkUrl,tvMap);
		}
	}
    
    private void tvRecordProcess(Page page, final Map<String, Object> tvMap)
   	{
   		Html html = page.getHtml();
   		String url = page.getUrl().toString();
   		if(StringUtils.isNotEmpty(url) && url.contains("vplay")){
   			String xid =url.substring(url.indexOf("vplay/")+6, url.indexOf(".html"));
   			String pids =html.xpath("//ul[@class='info_list']/li/em/a[@class='more']/@href").toString();
   			if(StringUtils.isNotEmpty(pids)){
   				String pid =pids.substring(pids.indexOf("movie/")+6, pids.indexOf(".html"));
   			//获取总页数
   			String jsonStr = HttpUtils.httpGetJSONP("http://api.my.le.com/vcm/api/list?jsonp=jQuery1710008671140181031767_1503977285792&cid=1"
						+ "&type=video&rows=20&page=1&sort=&source=1&listType=1"
						+ "&xid="+xid+""
						+ "&pid="+pid+""
						+ "&ctype=cmt%2Cimg%2Cvote");
   			jsonStr = jsonStr.substring(jsonStr.indexOf("{"));
   			jsonStr = jsonStr.substring(0, jsonStr.lastIndexOf("}") + 1);
   			JSONObject C_json = JSONObject.fromObject(jsonStr);
   			String totalPage = C_json.getString("total");
   			int pageSize =Integer.valueOf(totalPage);
   			pageSize = (int) Math.ceil((int) Math.ceil(((double)pageSize)/20));
   				
   			for (int i = 1; i <= pageSize; i++)
   			{
   				// 添加短评链接
   				PageUtils.addTargetRequest(page,
					"http://api.my.le.com/vcm/api/list?jsonp=jQuery1710008671140181031767_1503977285792&cid=1"
						+ "&type=video&rows=20&page="+i+"&sort=&source=1&listType=1"
						+ "&xid="+xid+""
						+ "&pid="+pid+""
						+ "&ctype=cmt%2Cimg%2Cvote",
						tvMap);
   				}
   			}
   		}
   	}
	
	private void commentProcess(Page page, Map<String, Object> tvMap)
	{
		System.out.println(page.getHtml().toString());
		String jsonStr = page.getRawText();
		// format json
		jsonStr = jsonStr.substring(jsonStr.indexOf("{"));
		
		jsonStr = jsonStr.substring(0, jsonStr.lastIndexOf("}") + 1);
		
		JSONObject C_json = JSONObject.fromObject(jsonStr);
		
		if (!C_json.containsKey("data"))
			throw new SpiderException(
					SpiderExceptionCode.DataInvalideException);
		
		JSONArray comments = C_json.getJSONArray("data");
		for (int i = 0; i < comments.size(); i++)
		{
			JSONObject comment = comments.getJSONObject(i);
			
			if (!comment.containsKey("content"))
				continue;
			
			if (!comment.containsKey("vtime")
					|| StringUtils.isEmpty(comment.getString("vtime")))
				continue;
			
			if (!comment.containsKey("user"))
				continue;
			String line = StringUtils.join(new String[]{StringUtil.nullToString(page.getRequest().getExtra("type")),
					KeywordEncode.decode((String)tvMap.get("movieName")), 
					comment.getJSONObject("user").getString("username").replace("'", "''"), 
					comment.getString("vtime"), 
					comment.getString("content").replace("'", "''")}, SepratorUtil
	                .SEP_PIPE);
	        System.out.println(line);
	        FileUtil.writeFile(LeTVComment, line + SepratorUtil.LINE_SEPRATOR);
		}
	}
    /**
     * 读取文件指定列
     *
     * @param fileName 文件名称
     * @return 行列表
     */
    public static List<JSONObject> readFileColumn(String fileName)
    {
        Map<String, Object> map = new HashMap<String, Object>();
        Workbook wb = null;
        String json;
        List<JSONObject> list = new ArrayList<JSONObject>();
        try
        {
            InputStream inputStream = new FileInputStream(fileName);
            if (fileName.endsWith("xls"))
            {
                wb = new HSSFWorkbook(inputStream); // 解析xls格式
            } else if (fileName.endsWith("xlsx"))
            {
                wb = new XSSFWorkbook(inputStream); // 解析xlsx格式
            }
            Sheet sheet = wb.getSheetAt(0); // 第一个工作表

            int firstRowNum = 1;
            int lastRowNum = sheet.getLastRowNum();

            Row row = null;
            Cell cell_a1 = null;
            for (int i = firstRowNum; i <= lastRowNum; i++)
            {
                row = sheet.getRow(i);          //取得第i行
                cell_a1 = row.getCell(0);      //取得i行的第一列
                if(row.getCell(0)!=null){
                	cell_a1.setCellType(Cell.CELL_TYPE_STRING);
                    String cellValue1 = cell_a1.getStringCellValue();
                    map.put("tvName", cellValue1);
               }
                json = new Gson().toJson(map);
                JSONObject jsStr = JSONObject.fromObject(json);
                list.add(jsStr);
            }

        }
        catch (FileNotFoundException e)
        {
            e.printStackTrace();
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
        return list;
    }
    
    @Override
    protected String getSpiderType()
    {
        return "LeTVCommentList";
    }
}
